package com.pxxy.lib_common.utils;

import android.annotation.SuppressLint;
import android.support.annotation.NonNull;
import android.util.Log;

import java.text.DateFormat;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * @author JunedQQ
 * @create 2019/5/26
 * @since 1.0.0
 */
public class TimeUtils {

    //默认格式化类型的DateFormat对象,yyyy-MM-dd HH:mm:ss：默认格式化类型
    @SuppressLint("SimpleDateFormat")
    private static final DateFormat DEFAULT_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    //getFitTimeSpan方法中的参数
    public static final String GETFITTIMESPAN_DAY = "day";
    public static final String GETFITTIMESPAN_HOURS = "hours";
    public static final String GETFITTIMESPAN_MINUTES = "minutes";
    public static final String GETFITTIMESPAN_SECONDS = "seconds";


    private TimeUtils() {
        throw new UnsupportedOperationException("TimeUtils 不能实例化...");
    }

    /**
     * 获取当前时间戳
     *
     * @return 返回字符串的时间戳
     */
    public static String getCurrentTime() {
        long msg = System.currentTimeMillis();
        return Long.toString(msg);
    }

    /**
     * 获取当前时间戳
     *
     * @return 返回long类型的时间戳
     */
    public static long getCurrentTimeAsLong() {
        long time = System.currentTimeMillis();
        return time;
    }

    /**
     * 获取当前格式化时间
     *
     * @return 当前格式化时间
     */
    public static String getCurrentTimeAsFormat() {
        return getCurrentTimeAsFormat(DEFAULT_FORMAT);
    }

    /**
     * 获取当前格式化时间，并可以指定显示格式
     *
     * @param format 传入已经配置好显示格式的dateFormat对象
     * @return 当前格式化时间
     */
    public static String getCurrentTimeAsFormat(DateFormat format) {
        long time = System.currentTimeMillis();
        return formatTime(time, format);
    }

    /**
     * 将时间戳转为格式化时间字符串
     * <p>输出的结构是: {@code yyyy-MM-dd HH:mm:ss}.</p>
     *
     * @param millis 时间戳，毫秒
     * @return 格式化的时间字符串
     */
    public static String formatTime(final long millis) {
        return formatTime(millis, DEFAULT_FORMAT);
    }

    /**
     * 将时间戳转为指定格式化时间字符串
     * <p>输出的结构由传入的DateFormat对象初始化时决定</p>
     *
     * @param millis 时间戳，毫秒
     * @param format 指定格式的DateFormat对象
     * @return 格式化的时间字符串
     */
    public static String formatTime(final long millis, @NonNull final DateFormat format) {
        return format.format(new Date(millis));
    }

    /**
     * 将时间字符串转为时间戳
     * <p>输出的结构是: {@code yyyy-MM-dd HH:mm:ss}.</p>
     *
     * @param time 格式化的时间字符串
     * @return 时间戳
     */
    public static long formatTimeToTimestamp(final String time) {
        return formatTimeToTimestamp(time, DEFAULT_FORMAT);
    }

    /**
     * 将时间字符串转为时间戳
     *
     * @param time   格式化的时间字符串。
     * @param format DateFormat对象
     * @return 时间戳
     */
    public static long formatTimeToTimestamp(final String time, @NonNull final DateFormat format) {
        try {
            return format.parse(time).getTime();
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return -1;
    }

    /**
     * 将时间字符串转为 Date 类型
     * <p>输出的结构是: {@code yyyy-MM-dd HH:mm:ss}.</p>
     *
     * @param time 格式化的时间字符串。
     * @return date对象
     */
    public static Date formatTimeToDate(final String time) {
        return formatTimeToDate(time, DEFAULT_FORMAT);
    }

    /**
     * 格式化的事件字符串转化为date对象
     *
     * @param time   格式化的时间字符串。
     * @param format DateFormat对象
     * @return date对象
     */
    public static Date formatTimeToDate(final String time, @NonNull final DateFormat format) {
        try {
            return format.parse(time);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取两个时间戳的时间差
     *
     * @param millis0 时间戳1（毫秒）
     * @param millis1 时间戳2（毫秒）
     * @return 时间差，List<Integer>对象
     * <p>   GETFITTIMESPAN_DAY  :    时间差中天数的Key </p>
     * <p>   GETFITTIMESPAN_HOURS :   时间差中小时的key </p>
     * <p>   GETFITTIMESPAN_MINUTES   :   时间差中分钟的key </p>
     * <p>   GETFITTIMESPAN_SECONDS   :   时间差中秒的key  </p>
     */
    public static Map<String, Integer> getFitTimeSpan(long millis0, long millis1) {
        return millisFitTimeSpan(Math.abs(millis0 - millis1));
    }

    /**
     * 计算时间差中的天，时，分，秒
     *
     * @param millis
     * @return 时间差，List<Integer>对象
     * <p>   GETFITTIMESPAN_DAY  :    时间差中天数的Key </p>
     * <p>   GETFITTIMESPAN_HOURS :   时间差中小时的key </p>
     * <p>   GETFITTIMESPAN_MINUTES   :   时间差中分钟的key </p>
     * <p>   GETFITTIMESPAN_SECONDS   :   时间差中秒的key  </p>
     */
    @SuppressLint("DefaultLocale")
    public static Map<String, Integer> millisFitTimeSpan(long millis) {
        int[] unitLen = {86400000, 3600000, 60000, 1000};//天，小时，分钟，秒
        //存放相差的值
        Map<String, Integer> map = new HashMap<>();
        //获取相隔天数
        int day = (int) (Math.floor(millis / unitLen[0]));
        //获取相隔小时
        int hours = (int) Math.floor((millis % unitLen[0]) / unitLen[1]);
        //获取相隔多少分钟
        int minutes = (int) Math.floor((millis % unitLen[1]) / unitLen[2]);
        //获取相隔多少秒
        int seconds = (int) Math.floor(millis % unitLen[2] / unitLen[3]);

        //把值存放在list中
        map.put(GETFITTIMESPAN_DAY, day);
        map.put(GETFITTIMESPAN_HOURS, hours);
        map.put(GETFITTIMESPAN_MINUTES, minutes);
        map.put(GETFITTIMESPAN_SECONDS, seconds);

        return map;
    }

    /**
     * 相对于现在显示的时间
     * 返回今天、昨天、前天、2019-10-10 四种格式
     *
     * @param date 格式化时间的字符串
     * @return 返回，今天，昨天，前天和日期四种
     */
    public static String relativeNowTime(String date) {

        String dateF = "yyyy-MM-dd";

        SimpleDateFormat sdf = new SimpleDateFormat(dateF);
        String nowDay = "";
        try {
            nowDay = sdf.format(sdf.parse(date));
        } catch (ParseException e) {
            e.printStackTrace();
        }

        //今天
        Calendar cal = Calendar.getInstance();
        String yday = sdf.format(cal.getTime());
        if (yday.equals(nowDay)) {
            return "今天";
        }

        //昨天
        cal = Calendar.getInstance();
        cal.add(Calendar.DATE, -1);
        yday = sdf.format(cal.getTime());
        if (yday.equals(nowDay)) {
            return "昨天";
        }

        //前天
        cal = Calendar.getInstance();
        cal.add(Calendar.DATE, -2);
        yday = sdf.format(cal.getTime());
        if (yday.equals(nowDay)) {
            return "前天";
        }
        return nowDay;
    }

    /**
     * 相对于现在显示的时间
     * 返回今天、昨天、前天、2019-10-10 四种格式
     *
     * @param date 时间戳
     * @return 返回今天、昨天、前天、2019-10-10 四种格式
     */
    public static String relativeNowTime(long date) {

        String dateF = "yyyy-MM-dd";
        SimpleDateFormat sdf = new SimpleDateFormat(dateF);
        String nowDay = "";

        try {
            nowDay = sdf.format(new Date(date));
        } catch (Exception e) {
            e.printStackTrace();
        }

        //今天
        Calendar cal = Calendar.getInstance();
        String yday = sdf.format(cal.getTime());
        if (yday.equals(nowDay)) {
            return "今天";
        }

        //昨天
        cal = Calendar.getInstance();
        cal.add(Calendar.DATE, -1);
        yday = sdf.format(cal.getTime());
        if (yday.equals(nowDay)) {
            return "昨天";
        }

        //前天
        cal = Calendar.getInstance();
        cal.add(Calendar.DATE, -2);
        yday = sdf.format(cal.getTime());
        if (yday.equals(nowDay)) {
            return "前天";
        }

        return nowDay;
    }

    /**
     * 得到目标时间相对于现在的详细时间
     *
     * @param date  格式化的字符串
     * @param formatType    格式化字符串的格式化类型
     * @return  返回目标时间相对于现在的详细时间
     */
    public static String relativeNowTimeDetails(String date,String formatType) {
        //获取相对于现在的时间
        String time = relativeNowTime(date);
        //获取详细时间
        //日期格式
        String dateFormat = "HH:mm";
        SimpleDateFormat format = new SimpleDateFormat(dateFormat);
        try {
            //获取详细时间
            String detailsTime = format.format(formatTimeToTimestamp(date,new SimpleDateFormat(formatType)));
            //拼接时间
            time = time + " " + detailsTime;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return time;
    }

    /**
     * 得到目标时间相对于现在的详细时间
     *
     * @param date  时间戳
     * @return  返回目标时间相对于现在的详细时间
     */
    public static String relativeNowTimeDetails(long date) {
        //获取相对于现在的时间
        String time = relativeNowTime(date);
        //获取详细时间
        //日期格式
        String dateFormat = "HH:mm";
        SimpleDateFormat format = new SimpleDateFormat(dateFormat);
        try {
            //获取详细时间
            String detailsTime = format.format(new Date(date));
            //拼接时间
            time = time + " " + detailsTime;
        } catch (Exception e) {
            e.printStackTrace();
        }

        return time;
    }
}
